﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SpeedSearch.FullText;
using System.IO;

namespace SpeedSearch.Forms
{

    public partial class FormCopyFiles : Form
    {

        List<DocFile> files;
        string dirCommon;

        public FormCopyFiles()
        {
            InitializeComponent();
        }

        private void FormCopyFiles_Load(object sender, EventArgs e)
        {
            ctlDirectory.TextChanged += new EventHandler(ctlDirectory_TextChanged);

#if DEBUG
            ctlDirectory.Directory = @"C:\Temp\CopyFiles";
#endif
        }

        private void btnCopy_Click(object sender, EventArgs e)
        {
            try
            {

                string dir = ctlDirectory.Directory;

                Dictionary<string, string> erros = new Dictionary<string, string>();

                Dictionary<FileInfo, FileInfo> filesToCopy = new Dictionary<FileInfo, FileInfo>();
                string curFile = null;
                try
                {
                    foreach (var file in files)
                    {
                        curFile = file.FullName;
                        FileInfo source = new FileInfo((string)file.FullName);
                        FileInfo target = new FileInfo((string)file.Tag);

                        if (!source.Exists)
                        {
                            erros.Add(curFile, "File not found: " + source.FullName);
                        }
                        else
                        {
                            bool copy = true;

                            if (chkOverride.Checked)
                                copy = !target.Exists;

                            if (copy && target.Exists && chkDistincts.Checked)
                            {
                                if (source.Length == target.Length || !FileHelper.HasChanged(source.LastWriteTime, target.LastWriteTime))
                                    copy = false;
                            }

                            if (copy)
                                filesToCopy.Add(source, target);
                        }
                    }
                }
                catch (Exception ex)
                {
                    erros.Add(curFile, ex.Message);
                }

                if (filesToCopy.Count > 0)
                {
                    progress.Minimum = 0;
                    progress.Value = 0;
                    progress.Maximum = filesToCopy.Count;
                    progress.Visible = true;
                    progress.Update();

                    int countOk = 0;
                    foreach (var pair in filesToCopy)
                    {
                        var source = pair.Key;
                        var target = pair.Value;
                        curFile = source.FullName;

                        if (target.Exists && target.IsReadOnly)
                            File.SetAttributes(target.FullName, FileAttributes.Normal);
                        try
                        {
                            if (!target.Directory.Exists)
                                target.Directory.Create();
                            source.CopyTo(target.FullName, true);

                            File.SetAttributes(target.FullName, FileAttributes.Normal);
                            File.SetCreationTime(target.FullName, source.CreationTime);
                            File.SetLastAccessTime(target.FullName, source.LastAccessTime);
                            File.SetLastWriteTime(target.FullName, source.LastWriteTime);
                            File.SetAttributes(target.FullName, source.Attributes);
                            countOk++;
                        }
                        catch (Exception ex)
                        {
                            if (!erros.ContainsKey(curFile))
                                erros.Add(curFile, ex.Message);
                            else
                                erros[curFile] += "\r\n" + ex.Message;
                        }
                        progress.Value++;
                    }
                    Program.ShowInformation("Arquivos copiados: " + countOk + "\r\nErros: " + erros.Count);
                }
                else
                {
                    Program.ShowInformation("Nenhum arquivo precisa ser copiado.");
                }
            }
            catch (Exception ex)
            {
                Program.ShowError(ex);
            }

        }

        void ctlDirectory_TextChanged(object sender, EventArgs e)
        {
            Program.RunSafe(() =>
                {
                    btnCopy.Enabled = ctlDirectory.IsValid;
                    SetTarget();
                });
        }

        void SetTarget()
        {
            bool isValid = ctlDirectory.IsValid;

            try
            {
                foreach (var file in files)
                {
                    if (isValid)
                    {
                        string dirFile = Path.GetDirectoryName(file.FullName);
                        string dir = chkFullName.Checked
                        ? dirFile.Substring(dirCommon.Length, dirFile.Length - dirCommon.Length)
                        : "";

                        while (dir.StartsWith("\\"))
                            dir = dir.Substring(1, dir.Length - 1);

                        file.Tag = string.IsNullOrWhiteSpace(ctlDirectory.Directory) ? "" : Path.Combine(ctlDirectory.Directory, dir, file.FileName);
                    }
                    else
                        file.Tag = "";
                }
            }
            catch (Exception ex)
            {
                Program.ShowError(ex);
            }

            grid.DataSource = null;
            grid.DataSource = files;
        }

        public static void ShoDialog(IWin32Window owner, List<DocFile> files)
        {
            using (var f = new SpeedSearch.Forms.FormCopyFiles())
            {
                f.files = files.OrderBy(p => p.FullName).ToList();
                f.grid.AutoGenerateColumns = false;

                // só checa se forem arquivos de mais de 1 diretório
                f.chkFullName.Checked = f.files.GroupBy(p => Path.GetDirectoryName(p.FullName.ToLower())).Count() > 1;

                List<string> fullNames = (from c in files select c.FullName.ToLower()).ToList();

                int min = (from c in fullNames select c.Length).Min();
                string dirCommon = "";
                int lastSep = 0;

                for (int i = 0; i < min; i++)
                {
                    string curChar = fullNames[0].Substring(i, 1);
                    if (curChar == "\\")
                        lastSep = i;
 
                    foreach (string fullName in fullNames)
                    {
                        string c = fullName.Substring(i, 1);
                        if (!(fullName.Length > i && c == curChar))
                        {
                            curChar = null;
                            break;
                        }
                    }
                    if (curChar != null)
                        dirCommon += curChar;
                    else
                        break;
                }
                f.lblDirCommon.Text = f.dirCommon = dirCommon.Substring(0, lastSep);

                f.SetTarget();

                f.grid.DataSource = files;

                f.ShowDialog(owner);
            }
        }

        private void chkFullName_CheckedChanged(object sender, EventArgs e)
        {
            Program.RunSafe(() => SetTarget());

        }

    }

}
